package com.abel.bigwater.dataserver.model.kming

import com.abel.bigwater.data.BcdString
import io.netty.buffer.ByteBuf

class TermCodeType : TermData(KmingDataType.TermDummy, 6) {

    var size: SizeType? = null

    var remote: RemoteType? = null

    /**
     * 终端编码为 6 字节，其中 2 个字节字母+8 位 BCD 码。 8 位 BCD 的最高一位为 0，剩下表
    示 7 位的流水号。例如水平旋翼 100m 口径脉冲远传水表流水号为 1234567，水表自编号为：
    Lm1234567,终端编码为： 0x4C 0x6D 0x01 0x23 0x45 0x67。
     */
    var codeBcd: BcdString? = null

    var fmt: String? = null
        get() = "${size!!.code}${remote!!.code}${codeBcd!!.bcdString!!.takeLast(7)}"

    override fun bufLength() = 6

    override fun parseBuf(buf: ByteBuf): Boolean {
        size = SizeType.findByCode(buf.readByte().toChar()).firstOrNull()
        remote = RemoteType.findByCode(buf.readByte().toChar())

        codeBcd = BcdString.create(buf, 4)

        return true
    }

    override fun pack(buf: ByteBuf) {
        assert(codeBcd?.size == 4)

        buf.alloc().buffer().apply {
            writeByte(size!!.code.toInt())
            writeByte(remote!!.code.toInt())

            writeBytes(codeBcd!!.hexArray)

            buf.writeBytes(this)
        }
    }
}

enum class SizeType(val code: Char, val diameter: Int, val fmt: String) {
    Stand15('A', 15, "立式"),
    Sit15('B', 15, "卧式"),

    Stand20('C', 20, "立式"),
    Sit20('D', 20, "卧式"),

    Stand25('E', 25, "立式"),
    Sit25('F', 25, "卧式"),

    Stand40('G', 40, "立式"),
    Sit40('H', 40, "卧式"),

    SingleJet50('R', 50, "单流旋翼"),
    MultiJet50('N', 50, "多流旋翼"),
    Horizon50('J', 50, "水平旋翼"),
    Vertical50('U', 50, "垂直旋翼"),

    SingleJet80('S', 80, "单流旋翼"),
    MultiJet80('N', 80, "多流旋翼"),
    Horizon80('K', 80, "水平旋翼"),
    Vertical80('V', 80, "垂直旋翼"),

    SingleJet100('T', 100, "单流旋翼"),
    MultiJet100('N', 100, "多流旋翼"),
    Horizon100('L', 100, "水平旋翼"),
    Vertical100('W', 100, "垂直旋翼"),

    Horizon150('M', 150, "水平旋翼"),
    Vertical150('X', 150, "垂直旋翼"),

    Horizon200('Y', 200, "水平旋翼"),
    Vertical200('Z', 200, "垂直旋翼"),

    Horizon250('P', 250, "水平旋翼"),

    OtherSize('Q', 0, "其他类型");

    companion object {
        fun findByCodeSize(code: Char, size: Int) = values().find { it.code == code && it.diameter == size }

        fun findByCode(code: Char) = values().filter { it.code == code }
    }
}

enum class RemoteType(val code: Char, val fmt: String) {
    DirectRemote('z', "直读远传"),
    PulseRemote('m', "脉冲远传"),
    SolidSealing('f', "液封式"),
    DrySealing('g', "干式"),
    SolidTear('c', "湿式可拆"),
    FullPointer('a', "全指针显示"),
    DigitDisplay('n', "带数字显示"),
    OtherType('x', "其他");

    companion object {
        fun findByCode(code: Char) = values().find { it.code == code }
    }
}